home *** CD-ROM | disk | FTP | other *** search
- .MODEL TINY
-
- public RandSeed
- public GetKey
-
- extrn InitScreen:near
- extrn Bottom:near
- extrn PrintLong:near
- extrn Print:near
- extrn TestSpace:near
- extrn GameOverPrompt:near
- extrn PrintPause:near
- extrn RemovePause:near
-
- LEVEL_WAIT_INIT equ 700
- START_POS equ 280
-
- HISCORE_POS equ 24
- SCORE_POS equ 264
- LEVEL_POS equ 424
-
-
- PREVIEW_POS equ 380
-
-
- .CODE
- ORG 100h
-
- Start proc near
-
- ; INITIALIZATION
- ; **************
-
- cld
-
- ; Test command line
- xor bx,bx
- xor dl,dl
- mov cl,byte ptr ds:[80h] ; Command line length
- cmd_loop:
- and cl,cl ;cl=0?
- je short cmd_loop_end
- mov al,byte ptr ds:[81h+bx]
- dec cl
- inc bx
- cmp al,' ' ;skip space
- jne short not_space
- cmp dl,10
- jne short cmd_loop
- xor dl,dl
- jmp short cmd_loop
- not_space:
- cmp dl,0
- je short get_minus
- push ax
- mov ax, word ptr StartLevel
- mov dl, 10
- mul dl
- mov word ptr StartLevel, ax
- pop ax
- sub al, byte ptr '0'
- add StartLevel,ax
- jmp short cmd_loop
- get_minus:
- cmp al,'-'
- jne cmd_error
- and cl,cl
- je cmd_error
- mov al,byte ptr ds:[81h+bx]
- dec cl
- inc bx
- cmp al,'p' ; preview mode
- je preview_mode
- cmp al,'l'
- jne cmd_error
- inc dx ; dx type boolean
- jmp short cmd_loop
- preview_mode:
- inc word ptr PreView
- jmp short cmd_loop
- cmd_loop_end:
- cmp word ptr StartLevel,0
- je short set_level
- cmp word ptr StartLevel,17
- jbe short level_ok
- cmd_error:
- lea dx, ErrorText
- mov ah,09h
- int 21h
- mov ax,0h
- int 21h
- set_level:
- mov word ptr StartLevel,1
- level_ok:
-
- ; Get old int 1ch
- mov ax,351ch ; Function 35 interrupt 1c
- int 21h ; Get interrupt adress
- mov word ptr OldInt1c,bx ; 1c clock tick
- mov ax,es
- mov word ptr OldInt1c+2,ax
-
- ; Store new int 1ch
- mov dx,offset _NewInt1c ; Set clock tick
- mov ax,251ch ; to point to NewInt1c
- int 21h
-
- ; Set ctrl/break int
- mov dx,offset quit
- mov al,23h
- int 21h
-
- ; Play again starts here
- restart:
- mov ax,word ptr StartLevel
- mov word ptr Level,ax
- mov word ptr Score,0
- mov word ptr Score+2,0
-
- call near ptr RandInit ; Initialize random numbers
- call near ptr InitScreen ; Initialize screen
-
- ; Print hiscore holder
- mov ah,02h
- mov dl,10
- int 21h
- mov dl,13
- int 21h
- lea dx, HiScoreName
- mov ah,09h
- int 21h
-
- ; Print first preview
- cmp PreView,0
- je no_init_preview
- mov ax,OldRand
- shl ax,1
- shl ax,1
- mov PreItem,ax
- mov si,1
- mov di,PREVIEW_POS
- call Print
- no_init_preview:
-
- ; Calculate clicks before next level change
- mov ax, LEVEL_WAIT_INIT ; wait level*700 clicks
- mov dx, word ptr Level ; befor next level change
- mov word ptr TimerInit,18
- sub word ptr TimerInit,dx
- mul dx
- mov word ptr LevelWait,ax ; set LevelWait to 18-level
-
- ; Print out level
- xor dx,dx
- mov ax,word ptr Level ; print level
- mov di,LEVEL_POS
- call PrintLong
-
- ; Print Hiscore
- mov dx, word ptr HiScore+2
- mov ax, word ptr Hiscore
- mov di, HISCORE_POS
- call PrintLong
-
- ; Main loop
- ; *********
-
- jmp short while_kbhit
- for_ever:
- cmp word ptr Timer,0
- jne short while_kbhit
- mov ax,word ptr TimerInit
- mov Timer,ax
- call near ptr Down ; go down
- or ax,ax
- jne while_kbhit
- jmp game_over
-
- while_kbhit:
- mov ah,0bh
- int 21h
- or al,al
- je short for_ever
-
- call near ptr GetKey ; al=getkey
-
- cmp al,'p'
- jne short not_p
- xor PreView,1
- jnz short prev_on
- call near ptr RemovePreView
- jmp not_p
- prev_on:
- call near ptr PrintPreView
- not_p:
- or al,al
- je zero_key
- xor ah,ah
- sub ax,'2'
- mov bx,ax
- cmp bx,7
- ja short while_kbhit
- shl bx,1
- jmp word ptr cs:jump_table2[bx]
- zero_key:
-
- call near ptr GetKey ; al=getkey
-
- ; switch(ch)
- cbw ; ax=al
- sub ax,72
- mov bx,ax
- cmp bx,8
- ja short while_kbhit
- shl bx,1
- jmp word ptr cs:jump_table[bx]
- go_left:
- push si
- mov si,-2
- call Move
- pop si
- jmp short while_kbhit
- go_right:
- push si
- mov si,2
- call Move
- pop si
- jmp short while_kbhit
- go_drop:
- call Drop
- or ax,ax
- je short game_over
- jmp short while_kbhit
- go_rotate:
- call Rotate
- jmp short while_kbhit
- inc_level:
- cmp Level,17
- jge short while_kbhit
- add LevelWait,LEVEL_WAIT_INIT
- inc word ptr Level
- dec word ptr TimerInit
- xor dx,dx
- mov ax,word ptr Level
- mov di,LEVEL_POS
- call PrintLong
- jmp while_kbhit
- game_over:
- mov Timer,0
- mov Paused,1
-
- ; Test for new hiscore
- mov dx,word ptr Score+2
- mov ax,word ptr Score
- cmp word ptr HiScore+2,dx
- ja no_hiscore
- jb short new_hi
- test_lsw:
- cmp word ptr HiScore,ax
- jb short new_hi
- jmp short no_hiscore
- new_hi:
- mov word ptr HiScore,ax
- mov word ptr Hiscore+2,dx
-
- ; Get name of hiscore holder
- lea dx, EnterName
- mov ah,09h
- int 21h
- mov dx, offset HiScoreData
- mov ah,0ah
- int 21h
- mov bl,HiScoreData+1
- inc bl
- xor bh,bh
- mov HiscoreName[bx],13
- inc bl
- mov HiscoreName[bx],'$'
-
-
- ; Get tetris filename
- push ds
- mov ah,30h
- int 21h
- mov ax,ds:[002ch]
- mov es,ax
- xor di,di
- mov ax,di
- mov cx,07fffh
- cld
- EnvLoop:
- repnz scasb
- cmp es:[di],ah
- jne EnvLoop
- or ch,10000000b
- neg cx
-
- mov si,cx
- inc si
- inc si
-
- push ds
- push es
- pop ds
- mov dx,si
- mov ax,3d00h + 010b ; 010b = read/write
- int 21h ; open tetris.com
- pop ds
-
- mov bx,ax ; file handle
- mov ax,4200h ; lseek from start of file
- mov dx,offset HiscoreName
- sub dx,0100h
- xor cx,cx ; cx:dx=hiscorename
- int 21h
-
- mov ah,40h
- mov cx,offset OldInt1c-offset HiScoreName ; number of bytes to write
- mov dx,offset HiScoreName
- int 21h
-
- mov ah,3eh ; close file
- int 21h
-
- no_hiscore:
- call near ptr GameOverPrompt
- yesno:
- call near ptr GetKey
- cmp al,'n'
- je quit
- cmp al,'y'
- jne yesno
- ; Play again!
- jmp restart
-
- ; Close down
- ; **********
- quit:
- mov dx,word ptr OldInt1c ; restore old
- mov bx,word ptr OldInt1c+2 ; interrupt 1c vector
- push ds
- mov ds,bx
- mov ax,251ch
- int 21h
- pop ds
-
- mov ax,0003h
- int 10h
- ; Enter dos
- mov ax,0
- int 21h
- Start endp
-
- jump_table label word
- dw go_rotate
- dw inc_level
- dw while_kbhit
- dw go_left
- dw while_kbhit
- dw go_right
- dw while_kbhit
- dw while_kbhit
- dw go_drop
- jump_table2 label word
- dw go_drop
- dw while_kbhit
- dw go_left
- dw go_rotate
- dw go_right
- dw while_kbhit
- dw inc_level
-
- _NewInt1c proc far
- push ax
- push bx
- push cx
- push dx
- push di
- push si
- push bp
- push ds
- push es
-
- mov bp,cs
- mov ds,bp
- pushf
- call dword ptr OldInt1c
-
- inc word ptr randseed
- cmp word ptr Timer,0
- je short pause
- cmp Paused,0
- je short pause_ok
- call RemovePause
- mov Paused,0
- pause_ok:
- dec word ptr Timer
- dec word ptr LevelWait
- jne short return
- mov word ptr LevelWait,LEVEL_WAIT_INIT
- cmp TimerInit,0
- je short return
- dec word ptr TimerInit
- inc word ptr Level
- xor dx,dx
- mov ax,word ptr Level
- mov di,LEVEL_POS
- call PrintLong
- jmp return
- pause:
- cmp Paused,0
- jne short return
- call PrintPause
- mov Paused,1
- return:
- pop es
- pop ds
- pop bp
- pop si
- pop di
- pop dx
- pop cx
- pop bx
- pop ax
-
- iret
- _NewInt1c endp
-
-
-
-
- Move proc near ; si=dPos
- push si
-
- xor si,si
- mov ax,word ptr Item
- add ax,word ptr Rotated
- mov di,word ptr Pos
- call near ptr Print ; remove old
-
- mov ax,word ptr Item
- add ax,word ptr Rotated
- mov di,word ptr Pos
- pop si
- add di,si
- push si
- call near ptr TestSpace ; test if room
- pop si
- push ax
- or ax,ax
- je short no_room
- add word ptr Pos,si ; ok, add Pos
- no_room:
- push si
- mov si,1
- mov ax,word ptr Item
- add ax,word ptr Rotated
- mov di,word ptr Pos
- call near ptr Print
- pop si
- pop ax
- ret
- Move endp
-
- Rotate proc near
- push si
- xor si,si
- mov ax,word ptr Item
- add ax,word ptr Rotated
- mov di,word ptr Pos
- call near ptr Print
-
- mov ax,word ptr Rotated
- inc ax
- mov bx,4
- cwd
- idiv bx
- mov ax,word ptr Item
- add ax,dx
- mov di,word ptr Pos
- call near ptr TestSpace
- or ax,ax
- je short no_room1
- mov ax,word ptr Rotated
- inc ax
- mov bx,4
- cwd
- idiv bx
- mov word ptr Rotated,dx
- no_room1:
-
- mov si,1
- mov ax,word ptr Item
- add ax,word ptr Rotated
- mov di,Pos
- call near ptr Print
- pop si
- ret
- Rotate endp
-
- Down proc near
- push si
- mov si,80
- call Move
-
- or ax,ax ; room?
- je get_new ; no
- pop si
- ret
- get_new:
- mov ax,word ptr Item
- add ax,word ptr Rotated
- mov di,word ptr Pos
- call near ptr Bottom ; reached the bottom
-
- call near ptr Rand7 ; get new item
- shl ax,1
- shl ax,1
- mov word ptr Item,ax
- mov word ptr Pos,START_POS
- mov word ptr Rotated,0
-
- ; Calculate score
- mov ax,word ptr Drops
- shr ax,1
- add ax,2
- sub ax,PreView
- mov dx,word ptr Level
- mul dx
- add Score,ax
- adc Score+2,dx
- mov di,SCORE_POS
- mov ax,Score
- mov dx,Score+2
- call PrintLong
- mov word ptr Drops,0
-
- ; Test if new tetris can be printed
- mov ax,word ptr Item
- add ax,word ptr Rotated
- mov di,Pos
- call TestSpace
- or ax,ax
- jne place_new
-
- ; There was no room. Return false!
- pop si
- ret
-
- ; There was room. Print tetris.
- place_new:
- mov si,1
- mov ax,word ptr Item
- add ax,word ptr Rotated
- mov di,Pos
- call Print
- mov ax, word ptr TimerInit
- mov word ptr Timer,ax
-
- ; Display preview tetris
- cmp PreView,0
- je short no_preview
- call near ptr RemovePreView
- call near ptr PrintPreview
- ; Return true.
- no_preview:
- mov ax,1
- pop si
- ret
- Down endp
-
- Drop proc near
- push si
- mov si,80
- drop_more:
- call Move
- inc word ptr Drops
- or ax,ax
- jne drop_more
-
- call near ptr Down
- pop si
- ret
- Drop endp
-
- PrintPreView proc near
- mov si,1
- mov ax,OldRand
- shl ax,1
- shl ax,1
- mov PreItem,ax
- mov di,PREVIEW_POS
- call Print
- ret
- PrintPreView endp
-
- RemovePreView proc near
- xor si,si
- mov ax,word ptr PreItem
- mov di,PREVIEW_POS
- call Print
- ret
- RemovePreView endp
-
-
- GetKey proc near
- mov ah,07h
- mov dl,0ffh
- int 21h
- ret
- GetKey endp
-
- RandInit proc near
- mov bp,sp
- sub sp,4
- mov ah,02h
- int 1ah
- mov [bp-2],cl
- mov [bp-4],dh
- mov ax,word ptr [bp-2]
- imul word ptr [bp-4]
- mov word ptr randseed,ax
- mov sp,bp
- call near ptr Rand7
- ret
- RandInit endp
-
- Rand7 proc near
- mov ax,word ptr randseed
- imul word ptr randseed
-
- test ax,1
- je short even_number
- add ax,3172
- mov word ptr randseed,ax
- jmp short skip_even
- even_number:
- shl ax,1
- add ax,Score
- skip_even:
- mov word ptr randseed,ax
- mov bx,7
- xor dx,dx
- div bx
- mov ax, word ptr OldRand
- mov word ptr OldRand, dx
- ret
- Rand7 endp
-
- .DATA
- Timer dw 0
- LevelWait dw LEVEL_WAIT_INIT
- Level dw 1
- StartLevel dw 0
- Pos dw START_POS
- Item dw 0
- Rotated dw 0
- Drops dw 0
- RandSeed dw 0
- PreView dw 0
- Paused db 0
- ErrorText db 'Bad arguments',10,'$'
- EnterName db 'Enter name:',10,13,'$'
- HiScoreData db 14,0
- HiScoreName db 15 dup ('$')
- HiScore dd 0
- OldInt1c db 4 dup (?)
- Score dw 2 dup (?)
- OldRand dw 1 dup (?)
- PreItem dw 1 dup (?)
- TimerInit dw 1 dup (?)
-
- end Start
-
-